package com.zzyl.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.zzyl.base.PageResponse;
import com.zzyl.constant.SuperConstant;
import com.zzyl.dto.UserDto;
import com.zzyl.entity.Role;
import com.zzyl.entity.User;
import com.zzyl.entity.UserRole;
import com.zzyl.enums.BasicEnum;
import com.zzyl.exception.BaseException;
import com.zzyl.mapper.*;
import com.zzyl.service.UserService;
import com.zzyl.utils.NoProcessing;
import com.zzyl.vo.UserVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

@Slf4j
@Service
public class UserServiceImpl implements UserService {
    @Autowired
    UserMapper userMapper;

    @Autowired
    RoleResourceMapper roleResourceMapper;

    @Autowired
    RoleMapper roleMapper;

    @Autowired
    DeptMapper deptMapper;

    @Autowired
    UserRoleMapper userRoleMapper;

    //分页查询
    @Override
    public PageResponse<UserVo> findUserPage(UserDto userDto, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        User user = BeanUtil.toBean(userDto, User.class);
        //需要处理岗位编号
        userDto.setDeptNo(NoProcessing.processString(userDto.getDeptNo()));
        Page<UserVo> page = userMapper.userPage(userDto);

        if (page != null) {
            page.forEach(item -> {
                //通过ID获得角色id
                Set<String> roleIds = roleResourceMapper.getRoleIdByUserId(item.getId());
                //将roleIds集合转为list集合
                List<String> roleIdList = new ArrayList<>(roleIds);
                //设置角色id
                item.setRoleVoIds(roleIds);
                //判断是否为空
                if (roleIds != null && roleIds.size() > 0) {
                    //通过角色id获得角色名称
                    Set<String> roleNames = roleMapper.getRoleNameByRoleId(roleIdList);
                    //设置角色名称
                    item.setRoleLabels(roleNames);
                }
            });
        }
        return PageResponse.of(page, UserVo.class);
    }
    //添加用户
    @Override
    @Transactional
    public UserVo addUser(UserDto userDto) {
        //根据部门编号查询，是否是最底层的部门，如果不是，不允许添加用户
        if (isLowestDept(userDto.getDeptNo())){
            throw new BaseException(BasicEnum.USER_LOCATED_BOTTOMED_DEPT);
        }
        //转换uservo为user
        User user = BeanUtil.toBean(userDto, User.class);
        user.setUsername(user.getEmail());
        user.setNickName(user.getRealName());
        user.setDataState(SuperConstant.DATA_STATE_0);
        //todo需要设置默认，并且需要加密
        String password = "bababbababbababababba";
        user.setPassword(password);

        int flag = userMapper.insert(user);
        //观察是否保存成功，返回主键是否等于0
        if (flag == 0){
            throw new RuntimeException("保存用户信息出错");
        }
        //保存用户角色中间表
        List<UserRole> userRoles = new ArrayList<>();
        userDto.getRoleVoIds().forEach(r -> {
            userRoles.add(UserRole.builder()
                    .userId(user.getId())
                    .roleId(Long.valueOf(r))
                    .dataState(SuperConstant.DATA_STATE_0)
                    .build());
        });
        flag = userRoleMapper.batchInsert(userRoles);
        if (flag == 0){
            throw new RuntimeException("保存用户角色中间表出错");
        }
        return BeanUtil.toBean(user, UserVo.class);
    }
    //判断是否是最低层部门
    private boolean isLowestDept(String deptNo) {
        int count = deptMapper.isLowestDept(deptNo);
        if (count > 0){
            return true;
        }
        return false;
    }
    //删除用户
    @Override
    public void deleteUserById(Long userId) {
        //删除用户角色中间表
        userRoleMapper.deleteUserRole(userId);
        //删除用户
        userMapper.deleteByUserId(userId);
    }
    //修改用户
    @Override
    public Boolean updateUser(UserDto userDto) {
        //更新表数据，只修改名字
        
        return true;
    }
}
